<?php

namespace App\Kuafu\Shop\Validate;

use App\Kuafu\Banner\Model\BannerCommonModel;
use App\Kuafu\Base\Enum\DBEnum;
use App\Kuafu\Base\Model\BaseModel;
use App\Kuafu\Base\Validate\BaseValidate;
use App\Kuafu\Shop\Enum\DeviceMerchantEnum;
use App\Kuafu\Pay\Model\PayStreamModel;
use App\Kuafu\ProductMenu\Model\ProductMenu;
use App\Kuafu\Shop\Enum\AreaCodeEnum;
use App\Kuafu\Shop\Model\AreaModel;
use App\Kuafu\Shop\Model\Shop;
use App\Kuafu\Shop\Model\ShopMonitorDataModel;
use App\Kuafu\User\Enum\UserCodeEnum;
use App\Kuafu\User\Exceptions\UserException;
use App\Kuafu\Shop\Model\ShopPaymentsModel;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;

class ShopValidate extends BaseValidate
{
    /**
     * 获取规则信息
     *
     * @param array $fields
     * @return string[]
     */
    public static function getRules(array $fields = []): array
    {
        return self::getActuallyRules([
            'mchId'            => 'required',
            'mchKey'           => 'required',
            'orderPrefix'      => 'required',
            'reservedFyTermId' => '',
            'date'             => 'required|date_format:Y-m-d',
            'unionPay'         => '',
            "source" => "required|int|in:0,1",

            'paymentId' => [
                'required',
                Rule::exists(ShopPaymentsModel::class, 'id')
                    ->when(!empty($fields['shopId']), function ($query) use ($fields) {
                        $query->where('shopId', $fields['shopId']);
                    })
                    ->where('isDeleted', BaseModel::DELETE_NO)
            ],
        ], $fields);
    }

    /**
     * 门店富有支付方式新增校验
     *
     * @param $params
     * @return array
     */
    public static function shopPaymentsInsertValidate($params): array
    {
        return self::baseValidate(
            $params,
            ['mchId', 'mchKey', 'orderPrefix', 'reservedFyTermId', 'source'],
            [],
            function (array $params) {
                $paramsObj = (object)$params;
                return [
                    'payConfig' => json_encode([
                        "mch_id"              => $paramsObj->mchId,
                        "mch_key"             => $paramsObj->mchKey,
                        "order_prefix"        => $paramsObj->orderPrefix,
                        "reserved_fy_term_id" => $paramsObj->reservedFyTermId ?? ''
                    ]),
                    'source' => $paramsObj->source
                ];
            }
        );
    }

    /**
     * 门店富有支付方式编辑校验
     *
     * @param $params
     * @return array
     */
    public static function shopPaymentsEditValidate($params): array
    {
        return self::baseValidate(
            $params,
            ['paymentId', 'mchId', 'mchKey', 'orderPrefix', 'reservedFyTermId', 'unionPay', 'source'],
            [],
            function (array $params) {
                $paramsObj = (object)$params;
                return [
                    'id'        => $paramsObj->paymentId,
                    'payConfig' => json_encode([
                        "mch_id"              => $paramsObj->mchId,
                        "mch_key"             => $paramsObj->mchKey,
                        "order_prefix"        => $paramsObj->orderPrefix,
                        "reserved_fy_term_id" => $paramsObj->reservedFyTermId ?? '',
                        'unionPay'            => $paramsObj->unionPay ?? 0
                    ]),
                    'source' => $paramsObj->source
                ];
            }
        );
    }


    /**
     * @param array $requestParams
     * @return array
     */
    public static function getFormalUseShopValidate(array $requestParams): array
    {
        return self::baseValidate($requestParams, ['date']);
    }

    public static function createShop(Request $request)
    {
        $rules = [
            'brandId'      => 'required|integer',
            'shopName'     => 'required|string',
            'shopCode'     => 'integer',
            'shopMobile'   => 'required|string|regex:/^1[3456789]\d{9}$/',
            'contact'      => 'required|string',
            'type'         => 'required|integer|between:0,2',
            'adRegionCode' => 'integer',
            'address'      => 'string',
            'prepare'      => 'integer',
        ];

//        if (!preg_match("/^1[3456789]\d{9}$/", $mobile)) {
//            throw new UserException(UserCodeEnum::ERR_USER_MOBILE);
//        }

        $messages = [];

        return self::validateCheck($request->all(), $rules, $messages);
    }

    public static function bindProductMenu(Request $request)
    {
        $rules = [
            'shopIds'       => [
                'required',
                'array',
                function ($attribute, $value, $fail) use ($request) {
                    foreach ($request->post('shopIds') ?? [] as $v) {
                        if (!is_int($v)) {
                            $fail('shopIds必须为int数组');
                        }
                    }
                }
            ],
            'productMenuId' => [
                'nullable',
                'integer',
            ],
        ];

        $messages = [];

        return self::validateCheck($request->toArray(), $rules, $messages);
    }

    public static function getBindMenuShops(Request $request)
    {
        $rules = [
            'productMenuId' => [
                'required',
                'integer',
                function ($attribute, $value, $fail) use ($request) {

                    $count = ProductMenu::query()
                                        ->where('id', $request->get('productMenuId'))
                                        ->where('status', DBEnum::STATUS_ON)
                                        ->count();
                    if (!$count) {
                        $fail('菜单未上架');
                    }
                }
            ],
            'pageSize'      => self::commonRules('pageSize'),
            'pageNum'       => self::commonRules('pageNum'),
        ];

        $messages = [];

        return self::validateCheck($request->all(), $rules, $messages);
    }


    public static function addOrSetShop(Request $request): string
    {
        $rules = [
            'formalUseAt'        => 'sometimes|string|date_format:Y-m-d',
            'name'               => [
                'required',
                'max:50',
                'min:1',
            ],
            'shopCode'           => [
//                'required',
                'max:9999',
                function ($attribute, $value, $fail) use ($request) {
                    if ($request->shopCode && Shop::query()
                                                  ->where(['shopCode' => $request->shopCode])
                                                  ->first()) {
                        $fail("店铺Code已存在");
                    }
                }
            ],
//            'imageUrl' => "required",
            'type'               => "required",
            "address"            => "required",
            "startAt"            => "required",
            "endAt"              => "required",
            'brandId'            => "required",
            'province'           => [
                'required',
                'integer',
                function ($attribute, $value, $fail) {
                    $exists = AreaModel::query()
                                       ->where('areaId', $value)
                                       ->where('level', AreaCodeEnum::AREA_PROVINCE)
                                       ->first();
                    if (empty($exists)) {
                        $fail("省份非法");
                    }
                }
            ],
            'city'               => [
                'required',
                'integer',
                function ($attribute, $value, $fail) {
                    $exists = AreaModel::query()
                                       ->where('areaId', $value)
                                       ->where('level', AreaCodeEnum::AREA_CITY)
                                       ->first();
                    if (empty($exists)) {
                        $fail("市级非法");
                    }
                }
            ],
            'district'           => [
                'required',
                'integer',
                function ($attribute, $value, $fail) {
                    $exists = AreaModel::query()
                                       ->where('areaId', $value)
                                       ->where('level', AreaCodeEnum::AREA_AREA)
                                       ->first();
                    if (empty($exists)) {
                        $fail("区域非法");
                    }
                }
            ],
            'lng'                => 'required|string|max:36',
            'lat'                => 'required|string|max:36',
            'branch'             => 'string|max:120',
            'privateDrainageImg' => 'string|max:120',
            'orderingQrCode'     => 'string|max:120',
            'status'             => 'integer|between:0,2'
        ];
        $data  = $request->all();
        if ($request->method() == "PUT") {
            $rules['shopId']       = ['required', 'integer'];
            $rules['serialNumber'] = 'string|max:100';
            $data['shopId']        = $request->shopId;
            $rules['shopCode']     = [
//                'required',
                'max:9999',
                function ($attribute, $value, $fail) use ($request) {
                    if ($request->shopCode && Shop::query()
                                                  ->where(['shopCode' => $request->shopCode])
                                                  ->where('id', '!=', $request->shopId)
                                                  ->first()) {
                        $fail("店铺Code已存在");
                    }
                }
            ];
        }
        $messages = [];
        return self::validateCheck($data, $rules, $messages);
    }

    public static function setShopStatus(Request $request): string
    {
        $rules          = [
            'status' => ['required', 'integer', 'between:0,2'],
            'shopId' => [
                function ($attribute, $value, $fail) use ($request) {
                    if (!Shop::query()
                             ->where(['id' => $request->shopId])
                             ->first()) {
                        $fail("店铺不存在或已删除");
                    }
                }
            ]
        ];
        $data['shopId'] = $request->shopId;
        $data['status'] = $request->status;
        $messages       = [];
        return self::validateCheck($data, $rules, $messages);
    }

    public static function getShopList($data)
    {
        $rules    = [
            'userId' => [
                'required',
                'integer',
                'min:0',
            ],
        ];
        $messages = [];

        return self::validateCheck($data, $rules, $messages);
    }

    public static function setShopTarget(Request $request)
    {
        $rules = [
            'shopId' => [
                function ($attribute, $value, $fail) use ($request) {
                    if (!Shop::query()
                             ->where(['id' => $request->shopId])
                             ->first()) {
                        $fail("店铺不存在或已删除");
                    }
                }
            ],
            'target' => 'required|integer|min:0',
        ];

        $messages = [];

        return self::validateCheck($request->all(), $rules, $messages);
    }

    public static function useShopStatus($request)
    {
        $rules = [
            'status' => 'required|integer|between:0,1',
        ];

        $messages = [];

        return self::validateCheck($request->all(), $rules, $messages);

    }

    public static function getUserDetail(array $array)
    {
        $rules = [
            'userId' => 'required|integer|min:0',
        ];

        $messages = [];

        return self::validateCheck($array, $rules, $messages);
    }


    public static function bandSerialNumber($request)
    {
        $rules = [
            'serialNumber' => 'required',
        ];

        $messages = [];

        return self::validateCheck($request->all(), $rules, $messages);
    }

    public static function bandDouYinSHop($request)
    {
        $rules = [
            'sourceType'    => 'required|integer',
            'thirdShopName' => '',
            'thirdShopId'   => 'required',
        ];

        $messages = [
            'sourceType.required'    => '请输入第三方来源',
            'thirdShopName.required' => '请输入抖音店铺名称',
            'thirdShopId.required'   => '请输入抖音poiId',
        ];

        return self::validateCheck($request->all(), $rules, $messages);
    }


    /**
     * @param  $request
     * @return string
     */
    public static function monitorData($request)
    {

        $rules = [
            'data' => [
                'required',
                'array',
                function ($attribute, $value, $fail) use ($request) {
                    foreach ($request['data'] as $v) {
                        if (!is_int($v['monitorId'])) {
                            $fail('data.monitorId必须为int');
                        }

                        if (!in_array($v['type'],
                            [ShopMonitorDataModel::TYPE_IN_SHOP, ShopMonitorDataModel::TYPE_PASS_SHOP])) {
                            $fail('data.type错误');
                        }

                        if (!is_int($v['dataAt'])) {
                            $fail('data.dataAt必须为int');
                        }

                        if (!is_int($v['count'])) {
                            $fail('data.count必须为int');
                        }
                    }
                }
            ],
        ];

        $messages = [];
        return self::validateCheck($request->all(), $rules, $messages);
    }

    /**
     * @param  $request
     * @return string
     */
    public static function temperatureData($request)
    {

        $rules = [
            'data' => [
                'required',
                'array',
                function ($attribute, $value, $fail) use ($request) {
                    foreach ($request['data'] as $v) {
                        if (!is_integer($v['monitorId'])) {
                            $fail('data.monitorId必须为int');
                        }


                        if (!is_int($v['dataAt'])) {
                            $fail('data.dataAt必须为int');
                        }

                        if (!is_numeric($v['temperature'])) {
                            $fail('data.temperature必须为int');
                        }
                    }
                }
            ],
        ];

        $messages = [];
        return self::validateCheck($request->all(), $rules, $messages);
    }


    public static function getTemperatureData($request)
    {
        $rules = [
            'monitorId' => 'required',
            'startTime' => 'required',
            'endTime'   => 'required',
            'pageSize'  => self::commonRules('pageSize'),
            'pageNum'   => self::commonRules('pageNum'),
        ];

        $messages = [
            'monitorId.required' => '请输入设备id',
            'startTime.required' => '请输入开始时间',
            'endTime.required'   => '请输入结束时间',
        ];

        return self::validateCheck($request->all(), $rules, $messages);
    }

    public static function getMonitorData(Request $request)
    {
        $rules    = [
            'showTimeTab'    => self::merchantCommonRules('showTimeTab'),
            'showStartAt'    => self::merchantCommonRules('showStartAt'),
            'showEndAt'      => self::merchantCommonRules('showEndAt'),
            'compareTimeTab' => self::merchantCommonRules('compareTimeTab'),
            'compareStartAt' => self::merchantCommonRules('compareStartAt'),
            'compareEndAt'   => self::merchantCommonRules('compareEndAt'),
            'statisticsType' => self::merchantCommonRules('statisticsType'),
        ];
        $messages = [];

        return self::validateCheck($request->all(), $rules, $messages);
    }

    private static function merchantCommonRules(string $param)
    {
        return [
            'showTimeTab' => [
                'required',
                'integer',
                function ($attribute, $value, $fail) {
                    if (!in_array($value, array_keys(DeviceMerchantEnum::SHOW_TIME_TAB_TEXT))) {
                        $fail("不支持的showTimeTab");
                    }
                }
            ],
            'showStartAt' => 'nullable|integer|min:0',
            'showEndAt'   => 'nullable|integer|min:0',

            'statisticsType' => [
                'required',
                'integer',
                function ($attribute, $value, $fail) use ($param) {
                    if (!in_array($value, array_keys(DeviceMerchantEnum::STAT_TEXT))) {
                        $fail("不支持的statisticsType");
                    }
                }
            ],
            'compareTimeTab' => [
                'required',
                'integer',
                function ($attribute, $value, $fail) use ($param) {
                    if (!in_array($value, array_keys(DeviceMerchantEnum::COMPARE_TIME_TAB_TEXT))) {
                        $fail("不支持的compareTimeTab");
                    }
                }
            ],
            'compareStartAt' => 'nullable|integer|min:0',
            'compareEndAt'   => 'nullable|integer|min:0',
        ][$param] ?? '';
    }
}
